package com.xnyzc.lhy.mis.service.impl.statical;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.DateUtil;

import com.xnyzc.lhy.mis.entity.cms.OaSysStaticalAnalyst;
import com.xnyzc.lhy.mis.entity.cms.StatisticalData;
import com.xnyzc.lhy.mis.entity.result.order.OaCOrderAssignStatusRes;
import com.xnyzc.lhy.mis.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.mis.mapper.statical.OaSysStaticalAnalystMapper;
import com.xnyzc.lhy.mis.service.statical.OaSysStaticalAnalystService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;

@Service
public class OaSysStaticalAnalystServiceImpl implements OaSysStaticalAnalystService {
    private final String TIME_CONDITION_NAME = "timestamp";
    private final String APPOINTMENT_CONDITION_NAME = "appointmentTime";
    private final String MILEAGES_TYPE = "mileage";
    private final String INQUIRES_COUNT_NAME = "inquiriesCount";
    private final String DEAL_COUNT_NAME = "dealCount";
    private final String TADIO_COUNT_NAME = "tadio";
    private final int MILEAGES = 21;
    private final int HOURS = 24;

    @Autowired
    private OaSysStaticalAnalystMapper oaSysStaticalAnalystMapper;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public Rv getIndexCurrentTimeStatical(String cityCode, String date, Integer channel) {
        if(CheckUtil.strIsEmpty(cityCode) && CheckUtil.strIsEmpty(date) && CheckUtil.objIsEmpty(channel)){
            throw PangException.create(EErrorCode.missingArg);
        }
        List<OaSysStaticalAnalyst> oaSysStaticalAnalysts = oaSysStaticalAnalystMapper.selectStaticalData(cityCode, date, channel, TIME_CONDITION_NAME);
        if(CheckUtil.objIsEmpty(oaSysStaticalAnalysts)){
            return Rv.wrap();
        }
        JSONObject res = getResultData(oaSysStaticalAnalysts, TIME_CONDITION_NAME);
        return Rv.wrap(res);
    }

    @Override
    public Rv getIndexAppointmentStatical(String cityCode, String date, Integer channel) {
        if(CheckUtil.strIsEmpty(date)){
            throw PangException.create(EErrorCode.missingArg);
        }
        List<OaSysStaticalAnalyst> oaSysStaticalAnalysts = oaSysStaticalAnalystMapper.selectStaticalData(cityCode, date, channel, APPOINTMENT_CONDITION_NAME);
        if(CheckUtil.objIsEmpty(oaSysStaticalAnalysts)){
            return Rv.wrap();
        }
        JSONObject res = getResultData(oaSysStaticalAnalysts, APPOINTMENT_CONDITION_NAME);
        return Rv.wrap(res);
    }

    @Override
    public Rv getIndexAssignStatical(String cityCode, String date) {
        if(CheckUtil.objIsEmpty(cityCode) && CheckUtil.objIsEmpty(date)){
            return Rv.wrap();
        }
        HashMap<String, Object> vehicleMap = getAssignStaticalData(cityCode, date);
        return Rv.wrap(vehicleMap);
    }

    @Override
    public Rv getIndexMileageStatical(String cityCode, String date,  Integer channel) {
        if(CheckUtil.strIsEmpty(date)){
            throw PangException.create(EErrorCode.missingArg);
        }
        List<OaSysStaticalAnalyst> oaSysStaticalAnalysts = oaSysStaticalAnalystMapper.selectStaticalData(cityCode, date, channel, APPOINTMENT_CONDITION_NAME);
        if(CheckUtil.objIsEmpty(oaSysStaticalAnalysts)){
            return Rv.wrap();
        }
        JSONObject res = getResultData(oaSysStaticalAnalysts, MILEAGES_TYPE);
        return Rv.wrap(res);
    }

    //统计指派和未指派情况
    private HashMap<String, Object> getAssignStaticalData(String cityCode, String date){
        List<OaCOrderAssignStatusRes> assignCounts = oaCOrderPersonalMapper.getAssignCountsByVehicleType(cityCode, date);
        HashMap<String, Object> vehicleMap = new HashMap<>();
        for(int n = 0;n<4;n++){
            int[] hoursValue = new int[24];
            for (int i = 0; i <assignCounts.size() ; i++) {
                if(assignCounts.get(i).getVehicleType() == n) {
                    hoursValue[Integer.valueOf(assignCounts.get(i).getTimeCounts())] = assignCounts.get(i).getCounts();
                }
            }
            vehicleMap.put(String.valueOf(n), hoursValue);
        }
        return vehicleMap;
    }
    //合并数据
    private String mergeData(String one,String two){
        HashMap oneMap = JSON.parseObject(one, HashMap.class);
        List<Integer> oneInquires = JSON.parseArray(JSON.toJSONString(oneMap.get(INQUIRES_COUNT_NAME)),Integer.class);
        List<Integer> oneDeal = JSON.parseArray(JSON.toJSONString(oneMap.get(DEAL_COUNT_NAME)), Integer.class);
        HashMap twoMap = JSON.parseObject(two, HashMap.class);
        List<Integer> twoInquires = JSON.parseArray(JSON.toJSONString(twoMap.get(INQUIRES_COUNT_NAME)),Integer.class);
        List<Integer> twoDeal = JSON.parseArray(JSON.toJSONString(twoMap.get(DEAL_COUNT_NAME)), Integer.class);
        DecimalFormat df = new DecimalFormat("0.0000");
        for (int i = 0; i < oneInquires.size(); i++) {
            if (twoInquires.get(i) == 0) {
                continue;
            }
            oneInquires.set(i, oneInquires.get(i) + twoInquires.get(i));
            oneDeal.set(i, oneDeal.get(i) + twoDeal.get(i));
        }
        oneMap.put(INQUIRES_COUNT_NAME, oneInquires);
        oneMap.put(DEAL_COUNT_NAME, oneDeal);
        String res = JSON.toJSONString(oneMap);
        return res;
    }
    //计算成交率
    private HashMap computeTadio(String dataStr){
        if(CheckUtil.strIsEmpty(dataStr)){
            return null;
        }
        List<Double> tadioCount = new ArrayList();
        DecimalFormat df = new DecimalFormat("0.####");
        HashMap mapData = JSON.parseObject(dataStr, HashMap.class);
        List<Integer> inquires = JSON.parseArray(JSON.toJSONString(mapData.get(INQUIRES_COUNT_NAME)), Integer.class);
        List<Integer> deal = JSON.parseArray(JSON.toJSONString(mapData.get(DEAL_COUNT_NAME)), Integer.class);
        for (int i = 0; i < inquires.size(); i++) {
            if(inquires.get(i) == 0){
                tadioCount.add(Double.valueOf("0"));
                continue;
            }
            tadioCount.add(Double.valueOf(df.format((deal.get(i).floatValue() / inquires.get(i).floatValue()))) * 100);
        }
        mapData.put(TADIO_COUNT_NAME,tadioCount);
        return mapData;
    }

    private JSONObject getResultData(List<OaSysStaticalAnalyst> oaSysStaticalAnalysts,String type){
        JSONObject res = null;
        String startStr = null;
        if(CheckUtil.objIsNotEmpty(oaSysStaticalAnalysts)){
        if(type.equals(APPOINTMENT_CONDITION_NAME)){
            startStr = oaSysStaticalAnalysts.get(0).getAtimeDatas();
        }else if(type.equals(TIME_CONDITION_NAME)){
            startStr = oaSysStaticalAnalysts.get(0).getCtimeDatas();
        }else{
            startStr = oaSysStaticalAnalysts.get(0).getMileageDatas();
        }
        }
        //有多个则合并后再输出
        if(oaSysStaticalAnalysts.size() > 1){
            for (int i = 1; i <oaSysStaticalAnalysts.size() ; i++) {
                String targetStr = null;
                if(type.equals(APPOINTMENT_CONDITION_NAME)){
                   targetStr = oaSysStaticalAnalysts.get(i).getAtimeDatas();
                }else if(type.equals(TIME_CONDITION_NAME)){
                   targetStr = oaSysStaticalAnalysts.get(i).getCtimeDatas();
                }else{
                   targetStr = oaSysStaticalAnalysts.get(i).getMileageDatas();
                }
                String mergedStr = mergeData(startStr, targetStr);
                startStr = mergedStr;
            }
            HashMap resMap = computeTadio(startStr);
            res = JSON.parseObject(JSON.toJSONString(resMap));
        }else{
            //只有一个则直接转换输出
            HashMap resMap = computeTadio(startStr);
            res = JSON.parseObject(JSON.toJSONString(resMap));
        }
        return res;
    }


}
